<template>
  <div>
    <div><a href="https://blog.csdn.net/weixin_55195734/article/details/125327836" target="_blank">连线参考</a></div>
    <div>默认情况下，用户不能在任何一对端口之间绘制一个以上的相同方向的链路，也不能绘制一个连接节点与自身的链路。请阅读链接验证的一般性讨论。
    </div>
    <div><a href="https://gojs.net.cn/samples/orgChartEditor.html" target="_blank">gojs数据存储与回显</a></div>
    <div>
      <div ref="myDiagramDrawLink3" id="myDiagramDrawLink3" style="border: solid 1px black; width:800px; height:800px"></div>
    </div>

    <div>
      <el-input type="textarea" :rows="2" v-model="diagramJson">
      </el-input>
      <el-button @click="handleSave">保存</el-button>
      <el-button @click="load">加载</el-button>
    </div>

    <DialogInput :visible.sync="dialogVisible" @comfirm="handleDialogInputComfirm"></DialogInput>
  </div>
</template>

<script>
import DialogInput from '@/components/dialog/DialogInput.vue'
import go from 'gojs'
let $ = go.GraphObject.make;
export default {
  components: {
    DialogInput,
  },
  mounted () {
    this.init3();
  },
  data () {
    return {
      diagram: null,
      diagramJson: "",
      diagramData: {
        nodeDataArray: [
          { key: "张三" },
          { key: "李四" },
          { key: "王宗合" }
        ],
        linkDataArray: [
          // no predeclared links
          { from: "张三", to: "李四", text: "认识" }
        ]
      },
      currentNodeLinkData: null, // 当前连线的信息
      dialogVisible: false,
      // 节点连线监听器
      nodeLinkListener: (nodeLinkData) => {
        this.currentNodeLinkData = nodeLinkData;
        this.dialogVisible = true
      },
      handleDialogInputComfirm: (value) => {
        if (!this.currentNodeLinkData) {
          return;
        }
        // 删除连线（因为手动连线在锚点上）
        for (let link of this.diagramData.linkDataArray) {
          if (link.__gohashid == this.currentNodeLinkData.__gohashid) {
            this.diagram.model.removeLinkData(link);
            break;
          }
        }
        // 新增连线（该api新增的连线的锚点是自动的）
        this.diagram.model.addLinkData({
          from: this.currentNodeLinkData.from,
          to: this.currentNodeLinkData.to,
          text: value
        });
      }
    }
  },
  methods: {
    init3 () {
      let _this = this;
      let circleDiameter = 100; // Node圆形的直径
      let linkPointerDiameter = 6; // Node连接点的直径、半径
      let linkPointerRadius = linkPointerDiameter / 2; // Node连接点半径
      let diagram = new go.Diagram("myDiagramDrawLink3");
      this.diagram = diagram;
      diagram.nodeTemplate =
        // Node布局默认是Panel.Position。
        // node里的GraphObject根据GraphObject.position来布局，GraphObject.position默认为Point(NaN, NaN)。
        $(go.Node, "Position",
          // 所有Shape支持的形状：https://gojs.net.cn/samples/shapes.html
          $(go.Panel, "Position",
            $(go.Shape, "Circle", {
              width: circleDiameter,
              height: circleDiameter,
              fill: "lightgray"
            }),
            // 4个锚点
            $(go.Shape, "Circle", {
              position: new go.Point(circleDiameter / 2 - linkPointerRadius, 0),
              width: linkPointerDiameter,
              height: linkPointerDiameter,
              portId: "top",
              toLinkable: true, // 是否允许连线从该端点进入
              fromLinkable: true, // 是否允许连线从该端点出发
            }),
            $(go.Shape, "Circle", {
              position: new go.Point(circleDiameter / 2 - linkPointerRadius, circleDiameter - linkPointerDiameter),
              width: linkPointerDiameter,
              height: linkPointerDiameter,
              portId: "bottom",
              toLinkable: true, // 是否允许连线从该端点进入
              fromLinkable: true, // 是否允许连线从该端点出发
            }),
            $(go.Shape, "Circle", {
              position: new go.Point(0, circleDiameter / 2 - linkPointerRadius),
              width: linkPointerDiameter,
              height: linkPointerDiameter,
              portId: "left",
              toLinkable: true, // 是否允许连线从该端点进入
              fromLinkable: true, // 是否允许连线从该端点出发
            }),
            $(go.Shape, "Circle", {
              position: new go.Point(circleDiameter - linkPointerDiameter, circleDiameter / 2 - linkPointerRadius),
              width: linkPointerDiameter,
              height: linkPointerDiameter,
              portId: "right",
              toLinkable: true, // 是否允许连线从该端点进入
              fromLinkable: true, // 是否允许连线从该端点出发
            }),
          ),
          $(go.Panel, "Auto",
            {
              position: new go.Point(0, circleDiameter + 10),
            },
            $(go.Shape, "Rectangle",
              {
                width: circleDiameter,
                height: 20,
                fill: "white"
              },
            ),
            $(go.TextBlock,
              {
                alignment: go.Spot.Center,
                font: "bold 10pt sans-serif",
                margin: new go.Margin(0, 0)
              },
              new go.Binding("text", "key"),
            ),
          )
        )

      diagram.linkTemplate =
        $(go.Link,
          { curve: go.Link.Bezier },             // 贝塞尔曲线
          $(go.Shape),                           // 线
          $(go.Shape, { toArrow: "Standard" }),  // 箭头
          $(go.TextBlock,                        // text
            new go.Binding("text", "text"))
        );


      diagram.addDiagramListener("LinkDrawn", function (e) {
        let linkData = e.subject.data; //这是这个线条的数据
        _this.nodeLinkListener(linkData);
      });

      //  同时要在linkTemplate 配置上 selectable: true,这样 再监听连线成功时 的回调中 调 
      // myDiagram.commandHandler.deleteSelection() 才行 ,才能删除这个连线。

      diagram.model =
        $(go.GraphLinksModel, {
          linkFromPortIdProperty: "fromPort",  // required information:
          linkToPortIdProperty: "toPort",      // identifies data property names
          ...this.diagramData
        });
    },
    handleSave () {
      this.diagramJson = this.diagram.model.toJson();
    },
    load () {
      this.diagram.model = go.Model.fromJson(this.diagramJson);
      // make sure new data keys are unique positive integers
      // var lastkey = 1;
      // this.diagram.model.makeUniqueKeyFunction = function(model, data) {
      //     var k = data.key || lastkey;
      //     while (model.findNodeDataForKey(k)) k++;
      //     data.key = lastkey = k;
      //     return k;
      // }
    }
  },
  //   watch () {
  //     diagramData: {
  //       handler(newValue, oldValue) {
  //         console.log(newValue, oldValue)
  //         console.log('numbers正在被侦听')
  //       },
  //       deep: true
  //       // immediate: true
  //     }
  //   }
  watch: {
    // "diagramData.linkDataArray": {
    //   handler (newValue, oldValue) {
    //     console.log("newValue", JSON.stringify(newValue));
    //     console.log("oldValue", JSON.stringify(oldValue));
    //   },
    //   deep: true,
    // immediate: true
    // }
  }

}
</script>

<style>
</style>